package com.module.imagelib.glide.utils;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

/**
 * Environment 环境 因无埃热萌特
 * InputStream(输入流):输入流是用来读入数据的。- - - > > >读入
 * OutputStream(输出流):输出流是用来写出数据的。- - - > > >写出
 *
 * mkdir：只能用来创建文件夹，且只能创建一级目录，如果上级不存在，就会创建失败。
 * mkdirs：只能用来创建文件夹，且能创建多级目录 ，如果上级不存在，就会自动创建。(创建文件夹多用此)
 * createNewFile:只能用来创建文件，且只能在已存在的目录下创建文件，否则会创建失败。(FileOutputStream os=new FileOutputStream(file)也可创建文件，看情况使用)
 * File.separator: /
 *
 * 内部存储(Internal Storage)：
 * 内部存储是App的私有目录，当一个应用卸载之后，内部存储中的这些文件也被删除。Shared Preferences和SQLite数据库文件都是存储在内部存储空间上的。
 * -context.getFileDir()
 * 路径：(data/data/应用包名/files),不过经实际测试(华为、小米手机等)，getFileDir实际路径为: /data/user/0/ 应用包名/files
 * -context.getCacheDir() 应用程序的缓存目录，该目录内的文件在设备内存不足时会优先被删除掉，所以存放在这里的文件是没有任何保障的，可能会随时丢掉。
 * 路径：(data/data/应用包名/cache),不过经实际测试(华为、小米手机等)，getCacheDir的手机路径为: /data//data/user/0/应用包名/cache
 *
 * 外部存储(External Storage)
 * 外部存储一般是指SDCard，外部存储中的文件是可以被用户或者其他应用程序修改的，外部存储中的目录实际上也分为两种:
 * -公共文件(目录):
 * Environment.getExternalStorageDirectory() 或 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).
 * SD卡的根目录，路径：/storage/emulated/0
 * -私有文件:由于是外部存储的原因即使是这种类型的文件也能被其他程序访问，只不过一个应用私有的文件对其他应用其实是没有访问价值的（恶意程序除外）。外部存储上，应用私有文件的价值在于卸载之后，这些文件也会被删除。类似于内部存储。
 * getApplicationContext().getExternalFilesDir("")
 * 路径：/storage/emulated/0/Android/data/应用包名/files
 * 扩展： getExternalFilesDir是手机中设置 → 应用 → 具体应用详情→ 清除数据 的操作对象
 * getApplicationContext().getExternalCacheDir()
 * 路径：/storage/emulated/0/Android/data/应用包名/cache
 * 扩展: getExternalCacheDir是手机中设置 → 应用 → 具体应用详情→ 清除缓存 的操作对象
 * 官方建议是，超过1MB的文件，建议存储到getExternalCacheDir()目录下
 *
 * context.getFilesDir() = /data/data/com.mt.mtpp/files
 * context.getCacheDir() = /data/data/com.mt.mtpp/cache
 * context.getExternalFilesDir() = /mnt/sdcard/Android/data/com.mt.mtpp/files
 * context.getExternalCacheDir() = /mnt/sdcard/Android/data/com.mt.mtpp/cache
 * Environment.getExternalStorageDirectory() = /mnt/sdcard
 * 内部存储（不会用）
 * Environment.getDataDirectory() = /data
 * Environment.getDownloadCacheDirectory() = /cache
 * Environment.getRootDirectory() = /system
 *
 * 参考：https://www.cnblogs.com/epmouse/p/5421048.html
 *
 * Created by dell on 2018/6/26
 */

public class ImageFileUtils {
    public static final String SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "other1";
//    public static final String DATAPATH = Environment.getDataDirectory().getAbsolutePath() + File.separator + "other";

    /**
     * 获取SD卡状态
     * 虚拟SD卡（内置的）
     * Environment.isExternalStorageEmulated();
     * 物理SD卡（可拆卸的）
     * Environment.isExternalStorageRemovable();
     */
    private static boolean gainPermission() {
        //SD卡正常挂载
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return true;
        }
        return false;
    }

    /**
     * 创建文件夹
     */
    private static void createDir() {
        File f = new File(SDPATH);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    /**
     * 创建文件
     */
    private static File createFile(String fileName) throws IOException {
        createDir();
        File file = new File(SDPATH, fileName);
        file.createNewFile();
        return file;
    }

    /**
     * 字符串保存到本地
     * 返回值：字符串写入本地是否成功
     * 思路：若文件存在，则删除；然后创建一个新的文件，并把数据写入文件
     */
    public static void write2File(String str, String fileName) {
        if (!gainPermission()) {
            return;
        }
        try {
            File file = createFile(fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(str.getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 字符串以流的形式保存到本地
     * 返回值：字符串写入本地是否成功
     * 思路：若文件存在，则删除；然后创建一个新的文件，并把数据写入文件
     * */
    public static void write2File(InputStream in, String fileName) {
        if (!gainPermission()) {
            return;
        }
        try {
            File file = createFile(fileName);
            FileOutputStream fos = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            while (in.read(bytes) > 0) {
                fos.write(bytes);
            }
            fos.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 从本地获取文件字符串
     * boolean cacheTime:缓存时间是否有效。true(有效)，文件存储时
     * 间超时，则不取;false(无效),不论文件是否超时，都取。
     * */
    public static String readFile2Str(String fileName) {
        String result = "";
        if (!gainPermission()) {
            return result;
        }
        try {
            File file = new File(SDPATH, fileName);
            if (!file.exists()) {
                return result;
            }
            FileInputStream fis = new FileInputStream(file);
            int length;
            byte[] bytes = new byte[fis.available()];
            while ((length = fis.read(bytes)) != -1) {
                result = new String(bytes, 0, length);
            }
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 把图片存入本地
     */
    public static String writeBitmap2File(Bitmap bitmap, String fileName) {
        String path = "";
        if (!gainPermission()) {
            return path;
        }
        try {
            File file = createFile(fileName);
            FileOutputStream fos = new FileOutputStream(file);
            //80%清晰度
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
            fos.flush();
            fos.close();
            path = file.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }

    /**
     * 从本地获取图片
     */
    public static Bitmap readFile2Bitmap(String fileName) {
        Bitmap bitmap = null;
        if (!gainPermission()) {
            return bitmap;
        }
        try {
            File file = new File(SDPATH, fileName);
            if (!file.exists()) {
                return bitmap;
            }
            FileInputStream fis = new FileInputStream(file);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            bitmap = BitmapFactory.decodeStream(fis, null, options);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }


    /**
     * 图片存入相册
     */
    public static void write2album(Context context, Bitmap bitmap) {
        //方法一 存到Pictures下：原1.55MB存后646KB
        String path = MediaStore.Images.Media.insertImage(context.getApplicationContext().getContentResolver(), bitmap, "", "");
        //方法二 先存到SD卡下，再存到Picture下：原1.55MB存后SD卡1.15MB/picture646KB
//        String path = ImageFileUtils.writeBitmap2File(bitmap, System.currentTimeMillis()+".jpg");
//        try {
//            path = MediaStore.Images.Media.insertImage(context.getApplicationContext().getContentResolver(), path, "", "");
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//            path = "";
//        }

        //发送通知刷新图库
        //4.4以后限制了系统应用才有权限使用广播通知系统扫描SD卡
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && !TextUtils.isEmpty(path)) {
            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            mediaScanIntent.setData(Uri.parse(path));
            context.getApplicationContext().sendBroadcast(mediaScanIntent);
        } else {
            context.getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
        }
    }

    /**
     * 文件复制
     */
    public static void copyFile(File source, File target) {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = new FileInputStream(source);
            out = new FileOutputStream(target);
            byte[] buffer = new byte[1024];
            while (in.read(buffer) > 0) {
                out.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void copyFile(File source) {
        File target = new File(SDPATH, System.currentTimeMillis() + ".jpg");
        copyFile(source, target);
    }

    //通过文件名删除文件
    public static boolean deleteFile(String fileName) {
        boolean ret = false;
        File file = new File(SDPATH, fileName);
        if (file.exists()) {
            file.delete();
            ret = true;
        }
        return ret;
    }


    /**
     * 弃用
     * file地址：storage/emulated/0/Android/data/com.dengqi.mymodule/files/camera/target.jpg
     * file转uri.getPath()：/name4/camera/target.jpg
     * new File(path)：会导致file不存在
     */
    public static File uri2File(Uri uri) {
        return new File(uri.getPath());
    }


    /**
     * 获取指定文件夹内所有文件大小的和
     */
    public static String getFormatSize(File file) {
        long size = getFolderSize(file);
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            return size + "B"; //Byte
        }
        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }
        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }
        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }

    private static long getFolderSize(File file) {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (File aFileList : fileList) {
                if (aFileList.isDirectory()) {
                    size = size + getFolderSize(aFileList);
                } else {
                    size = size + aFileList.length();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }
}